package com.think.cloud.thinkshop.mall.service.category.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.think.cloud.thinkshop.mall.controller.admin.category.vo.ProductCategoryLevelVO;
import com.think.cloud.thinkshop.mall.controller.admin.category.vo.ProductRelationCategoryReqVO;
import com.think.cloud.thinkshop.mall.convert.category.ProductCategoryConvert;
import com.think.cloud.thinkshop.mall.domain.Product;
import com.think.cloud.thinkshop.mall.domain.ProductCategory;
import com.think.cloud.thinkshop.mall.mapper.ProductCategoryMapper;
import com.think.cloud.thinkshop.mall.mapper.ProductMapper;
import com.think.cloud.thinkshop.mall.service.category.IProductCategoryService;
import com.think.common.core.exception.enums.ErrorCode;
import com.think.common.core.exception.util.ServiceExceptionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品类目Service业务层处理
 *
 * @author zkthink
 * @date 2024-05-08
 */
@Service
public class ProductCategoryServiceImpl implements IProductCategoryService {
    @Autowired
    private ProductCategoryMapper productCategoryMapper;

    @Autowired
    private ProductMapper productMapper;

    /**
     * 查询商品类目
     *
     * @param categoryId 商品类目主键
     * @return 商品类目
     */
    @Override
    public ProductCategory selectProductCategoryByCategoryId(Long categoryId) {
        return productCategoryMapper.selectById(categoryId);
    }

    /**
     * 查询商品类目列表
     *
     * @return 商品类目
     */
    @Override
    public List<ProductCategoryLevelVO> getProductTree() {
        List<ProductCategoryLevelVO> levelVOList =
                ProductCategoryConvert.INSTANCE.convertList(productCategoryMapper.selectList(new LambdaQueryWrapper<>()));
        if (CollectionUtils.isEmpty(levelVOList)) return levelVOList;
        // 插入关联商品数量
        List<ProductCategoryLevelVO> relationCountList = productCategoryMapper.getRelationProductCount();
        if (CollectionUtils.isNotEmpty(relationCountList)) {
            Map<Long, Integer> relationCountMap =
                    relationCountList.stream().collect(Collectors.toMap(ProductCategoryLevelVO::getCategoryId,
                            ProductCategoryLevelVO::getRelationCount));
            levelVOList.forEach(res -> {
                res.setRelationCount(ObjectUtil.isNotNull(relationCountMap.get(res.getCategoryId())) ?
                        relationCountMap.get(res.getCategoryId()) : 0);
            });
        }
        Map<Long, List<ProductCategoryLevelVO>> levelVOListMap =
                levelVOList.stream().collect(Collectors.groupingBy(ProductCategoryLevelVO::getParentCategoryId));
        List<ProductCategoryLevelVO> oneLevelList = levelVOListMap.get(0l);
        for (ProductCategoryLevelVO oneLevelVO : oneLevelList) {
            oneLevelVO.setPath(oneLevelVO.getName());
            List<ProductCategoryLevelVO> twoLevelList = levelVOListMap.get(oneLevelVO.getCategoryId());
            if (CollectionUtils.isEmpty(twoLevelList)) continue;
            for (ProductCategoryLevelVO twoLevelVO : twoLevelList) {
                twoLevelVO.setPath(oneLevelVO.getPath() + "/" + twoLevelVO.getName());
                List<ProductCategoryLevelVO> threeLevelList = levelVOListMap.get(twoLevelVO.getCategoryId());
                if (CollectionUtils.isEmpty(threeLevelList)) continue;
                threeLevelList.forEach(res -> res.setPath(twoLevelVO.getPath() + "/" + res.getName()));
                twoLevelVO.setChild(sortByWeight(threeLevelList));
            }
            oneLevelVO.setChild(sortByWeight(twoLevelList));
        }
        return sortByWeight(oneLevelList);
    }

    @Override
    public List<ProductCategory> selectProductCategoryList(ProductCategory productCategory) {
        return productCategoryMapper.selectList(productCategory);
    }

    private List<ProductCategoryLevelVO> sortByWeight(List<ProductCategoryLevelVO> list) {
        return list.stream()
                .sorted(Comparator.comparing(ProductCategoryLevelVO::getWeight).reversed())
                .collect(Collectors.toList());
    }

    /**
     * 新增商品类目
     *
     * @param productCategory 商品类目
     * @return 结果
     */
    @Override
    public int insertProductCategory(ProductCategory productCategory) {
        if (check(productCategory))  throw ServiceExceptionUtil.exception(ErrorCode.CATEGORY_NAME_EXIST_ERROR);
        return productCategoryMapper.insert(productCategory);
    }

    /**
     * 修改商品类目
     *
     * @param productCategory 商品类目
     * @return 结果
     */
    @Override
    public int updateProductCategory(ProductCategory productCategory) {
        if (check(productCategory)) throw ServiceExceptionUtil.exception(ErrorCode.CATEGORY_NAME_EXIST_ERROR);
        return productCategoryMapper.updateById(productCategory);
    }

    /**
     * 校验名称是否重复
     *
     * @param productCategory
     * @return
     */
    private boolean check(ProductCategory productCategory) {
        return productCategoryMapper.exists(new LambdaQueryWrapper<ProductCategory>()
                .eq(ProductCategory::getName, productCategory.getName())
                .ne(ObjectUtil.isNotNull(productCategory.getCategoryId()), ProductCategory::getCategoryId, productCategory.getCategoryId())
        );
    }

    /**
     * 批量删除商品类目信息
     *
     * @param categoryIds 主键集合
     * @return 结果
     */
    @Override
    public int batchDelete(List<Long> categoryIds) {
        return productCategoryMapper.deleteBatchIds(categoryIds);
    }

    @Override
    public void cancel(List<Long> productIds) {
        productMapper.update(null, new LambdaUpdateWrapper<Product>()
                .set(Product::getCategoryId, null).in(Product::getProductId, productIds));
    }

    @Override
    public void relation(ProductRelationCategoryReqVO vo) {
        productMapper.update(null, new LambdaUpdateWrapper<Product>()
                .set(Product::getCategoryId, vo.getCategoryId()).in(Product::getProductId, vo.getProductIds()));
    }

    @Override
    public Long findIdByName(String name) {
        return productCategoryMapper.selectOne(
                Wrappers.<ProductCategory>lambdaQuery().eq(ProductCategory::getName,name)
        ).getCategoryId();
    }
}
